home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Utils / makedep / makedep.c < prev    next >
C/C++ Source or Header  |  1990-08-16  |  8KB  |  334 lines

  1. /*
  2.  * Program to construct dependency lines for makefiles.
  3.  *
  4.  * Marvin Theimer and Tim Mann, 3/18/84.
  5.  *
  6.  * Hacked about by oystr, 12/29/84, to reformat
  7.  * output (-l), handle Concurrent Euclid source (-CE)
  8.  * and put ~eden on the default directory list (-E).
  9.  *
  10.  * Synopsis
  11.  *    makedep [options] [source files]
  12.  *
  13.  * Discussion
  14.  *   Makedep constructs a makefile-style dependency list
  15.  *   showing which header files the object files constructed
  16.  *   from the given source files depend
  17.  *   upon.  The dependency of the object file upon the source 
  18.  *   file is not indicated in the output; this dependency can 
  19.  *   usually be inferred by the make program.
  20.  *
  21.  *   Makedep handles nested includes properly, propagating
  22.  *   dependencies of one header file upon another back to
  23.  *   each object file whose source file includes the dependent
  24.  *   header file.
  25.  *
  26.  * Options
  27.  *   -o outfile
  28.  *    Output file name.  The default is "dependencies".  The name "-" 
  29.  *    indicates standard output.
  30.  *
  31.  *   -I dir
  32.  *    Add "dir" to the include file search list.  Multiple
  33.  *    -I options accumulate, building the search list from
  34.  *    left to right, with the system include directories
  35.  *    added at the end.  The space separating the directory
  36.  *    name from the -I may be omitted.  Directory names
  37.  *    may be given relative to the directory from which
  38.  *    makedep is invoked.  
  39.  *
  40.  *   -U
  41.  *    Use the standard Unix header directories as the system
  42.  *    search list.  Equivalent to specifying -I/usr/include after
  43.  *    all other -I options.
  44.  *
  45.  *   -V
  46.  *    Use the standard V-System header directories as the
  47.  *    system search list.  Equivalent to specifying the options
  48.  *    -I/usr/sun/include -I/usr/local/include -I/usr/include after
  49.  *    all other -I options.
  50.  *
  51.  *   -xV
  52.  *    Use the experimental V-System header directories as the
  53.  *    system search list.  Equivalent to specifying the options
  54.  *    -I/usr/sun/xinclude -I/usr/sun/include -I/usr/local/include
  55.  *    -I/usr/include after all other -I options.
  56.  *
  57.  *   -N
  58.  *    Use no system search list.  Suppresses the warning message 
  59.  *    ordinarily printed when a header file cannot be found.  This
  60.  *    option is useful when you are not interested in dependencies
  61.  *    on system include files.
  62.  *
  63.  *   -e ext
  64.  *    Object files have extension ".ext".  Defaults to .b if -V or -xV
  65.  *    is specified, .o otherwise.
  66.  *
  67.  *   -d
  68.  *    Turn on debug output.  Useful only to the maintainers.
  69.  *
  70.  *   -l
  71.  *    Print out dependency list with a single line for each
  72.  *    .o dependency. E.g.
  73.  *        x.o: y.h
  74.  *        x.o: z.h
  75.  *    Useful in the Eden configuration stuff.
  76.  *
  77.  *   -CE
  78.  *    Use Concurrent Euclid include syntax and add the usual
  79.  *    EdenLibrary and Eject library directories to the default
  80.  *    directory list.
  81.  *
  82.  *   -E
  83.  *    Put ~eden on default directory list.
  84.  *
  85.  *   If the source files depend on any header files in standard system 
  86.  *   include directories, one of the options -U, -V, -xV, or -N should 
  87.  *   normally be specified.  These four options are mutually exclusive.
  88.  *   If none of these options is given, only the directories specified 
  89.  *   in -I options are included in the search list (as with the -N flag), 
  90.  *   but warning messages are still printed for any header files that
  91.  *   cannot be found.
  92.  */
  93.  
  94. #include "makedep.h"
  95.  
  96. extern FILE *freopen();
  97.  
  98.  
  99. main(argc, argv)
  100.     int argc;
  101.     char **argv;
  102.   {
  103.  
  104.     Debug = 0;
  105.  
  106.     Initialize();
  107.     ProcessCommandLine(argc, argv);
  108.     /* Redirect stdout to the output file. */
  109.     if (strcmp(OutputFileName, "-") != 0)
  110.        {
  111.         if (freopen(OutputFileName, "w", stdout) == NULL)
  112.           {
  113.         fprintf(stderr, "%s: can't open %s for writing.\n", 
  114.         MyName, OutputFileName);
  115.         perror(OutputFileName);
  116.         exit(errno);
  117.       }
  118.       }
  119.     GenIncludeFileDependencies();
  120.     PrintDependencies();
  121.  
  122.     exit(0);
  123.   }
  124.  
  125.  
  126. /*
  127.  * Initialize various program data structures and variables.
  128.  */
  129.  
  130. Initialize()
  131.   {
  132.  
  133.     /* Set up default option flag settings. */
  134.     NFlag = FALSE;
  135.     UFlag = FALSE;
  136.     VFlag = FALSE;
  137.     xVFlag = FALSE;
  138.     eFlag = FALSE;
  139.     lFlag = CEFlag = FALSE;
  140.     
  141.     /* Set up default source and object extensions. */
  142.     strcpy(ObjExt, DefaultObjExt);
  143.  
  144.     /* Set up default output filename. */
  145.     strcpy(OutputFileName, DefaultOutputFileName);
  146.  
  147.     /* Set up default search list for include files. */
  148.     InclDirs = MakeList();
  149.     UserInclDirs = MakeList();    /* Empty to begin with. */
  150.  
  151.     /* Set up default source directory list. */
  152.     SrcFiles = MakeList();
  153.   }
  154.  
  155.  
  156. /*
  157.  * ProcessCommandLine:
  158.  * Process user's command line.
  159.  */
  160.  
  161. ProcessCommandLine(argc, argv)
  162.     int argc;
  163.     char **argv;
  164.   {
  165.     int nArg = 1;
  166.     char *p;
  167.  
  168.     MyName = argv[0];
  169.  
  170.     /* Parse command line options. */
  171.     while (nArg < argc)
  172.       {
  173.         if ( argv[nArg][0] == '-' )
  174.       {
  175.         switch (argv[nArg][1] )
  176.           {
  177.                 case 'o':
  178.             if (argv[nArg][2] == '\0')
  179.               {
  180.             p = argv[nArg+1];
  181.                 /* Name is a separate input arg. */
  182.             nArg++;    /* Incr. over the input arg. */
  183.               }
  184.             else
  185.               {
  186.             p = &(argv[nArg][2]);
  187.                 /* Name is tacked onto the -o directly. */
  188.               }
  189.             strcpy(OutputFileName, p);
  190.             break;
  191.  
  192.             case 'I':
  193.             if (argv[nArg][2] == '\0')
  194.               {
  195.             AddList(argv[nArg+1], UserInclDirs);
  196.                 /* Name is a separate input arg. */
  197.             nArg++;    /* Incr. over the input arg. */
  198.               }
  199.             else
  200.               {
  201.             AddList(&(argv[nArg][2]), UserInclDirs);
  202.                 /* Name is tacked onto the -I directly. */
  203.               }
  204.                   break;
  205.  
  206.             case 'N':
  207.             NFlag = TRUE;
  208.                   break;
  209.  
  210.             case 'U':
  211.             UFlag = TRUE;
  212.             AddDefaultDirectoryLists(DefaultUnixInclDirs, InclDirs);
  213.                   break;
  214.  
  215.         case 'V':
  216.             VFlag = TRUE;
  217.             AddDefaultDirectoryLists(DefaultVInclDirs, InclDirs);
  218.             if (!eFlag) strcpy(ObjExt, DefaultVObjExt);
  219.             break;
  220.  
  221.             case 'x':  /* xV */
  222.             if (argv[nArg][2] != 'V') 
  223.             goto badswitch;  /* sorry, Edsger */
  224.             xVFlag = TRUE;
  225.             AddDefaultDirectoryLists(DefaultXVInclDirs, InclDirs);
  226.             if (!eFlag) strcpy(ObjExt, DefaultVObjExt);
  227.                   break;
  228.  
  229.         case 'C': /* CE */
  230.             if (argv[nArg][2] != 'E')
  231.             goto badswitch;/* me too, Edsger. They did it first */
  232.             CEFlag = TRUE;
  233.             AddDefaultDirectoryLists(DefaultCEInclDirs, InclDirs);
  234.             break;
  235.  
  236.         case 'E': /* Eden */
  237.             AddDefaultDirectoryLists(DefaultEInclDirs, InclDirs);
  238.             break;
  239.  
  240.             case 'e':
  241.             eFlag = TRUE;
  242.             if (argv[nArg][2] == '\0')
  243.               {
  244.             p = argv[nArg+1];
  245.                 /* Name is a separate input arg. */
  246.             nArg++;    /* Incr. over the input arg. */
  247.               }
  248.             else
  249.               {
  250.             p = &(argv[nArg][2]);
  251.                 /* Name is tacked onto the -e directly. */
  252.               }
  253.             strcpy(ObjExt, p);
  254.                   break;
  255.  
  256.         case 'd':
  257.             Debug = TRUE;
  258.             break;
  259.  
  260.         case 'l':
  261.             lFlag = TRUE;
  262.             break;
  263.  
  264.          default:
  265.         badswitch:
  266.             fprintf(stderr, "%s: Unknown switch: %s\n", 
  267.             MyName, argv[nArg]);
  268.             exit(1);
  269.           }
  270.       }
  271.     else            /* No more options */
  272.       {
  273.         break;
  274.       }
  275.     nArg++;
  276.       }
  277.  
  278.     if (NFlag + UFlag + VFlag + xVFlag > 1)
  279.       {
  280.     fprintf(stderr, "%s: -N, -U, -V, and -xV are mutually exclusive.\n",
  281.         MyName);
  282.     exit(1);
  283.       }
  284.  
  285.     /* Add source files for which dependencies are to be found. */
  286.     while (nArg < argc)
  287.       {
  288.     AddList(argv[nArg], SrcFiles);
  289.     nArg++;
  290.       }
  291.  
  292.     /* Merge the list of user include directories with the list of "regular"
  293.        include directories to get the final search path. */
  294.     MergeLists(UserInclDirs, InclDirs);
  295.  
  296.     if (Debug)
  297.       {
  298.     printf("NFlag: %d, UFlag: %d, VFlag: %d, xVFlag",
  299.         NFlag, UFlag, VFlag, xVFlag);
  300.     printf("    ObjExt: %s\n", ObjExt);
  301.     printf("output filename: %s\n", OutputFileName);
  302.     PrintList(SrcFiles, "SrcFiles");
  303.     PrintList(InclDirs, "InclDirs");
  304.     PrintList(UserInclDirs, "UserInclDirs");
  305.       }
  306.   }
  307.  
  308.  
  309. /*
  310.  * AddDefaultDirectoryLists:
  311.  * Adds the directory names in dirs to the list l.
  312.  * The names in dirs are separated by blanks.
  313.  */
  314.  
  315. AddDefaultDirectoryLists(dirs, l)
  316.     char *dirs;
  317.     StringList l;
  318.   {
  319.     char *p, *p1;
  320.  
  321.     p = dirs;
  322.     while (*p != '\0')
  323.       {
  324.     for (p1 = p; ((*p1 != ' ') && (*p1 != '\0')); p1++)
  325.         ;
  326.     while (*p1 == ' ')
  327.       {
  328.         *p1++ = '\0';
  329.       }
  330.     AddList(p, l);
  331.     p = p1;
  332.       }
  333.   }
  334.